package ekahau.positioning.services.providor.server;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import org.eclipse.swt.graphics.Point;
import org.osgi.framework.Bundle;

import ekahau.positioning.client.ui.ActivatorPlugin;
import ekahau.positioning.client.ui.navigator.NavigationView;
import ekahau.positioning.client.ui.navigator.NavigationView.TagInfo;
import ekahau.positioning.services.providor.RestaurantsDB;
import ekahau.positioning.services.providor.ServicesClientRequest;
import ekahau.positioning.services.providor.ServicesClientResponse;
import ekahau.ue.registration.RegistrationClientRequest.PREFERENCE_TYPE;



public class ServicesProvidor extends Thread{
    
	private Vector<EkahauClientListener> playerList = new Vector();
	
	private Vector<String> roomsList = new Vector<String>();
	
	private Vector<Point> R1501Point = new Vector<Point>() ;
	private Vector<Point> R1506Point = new Vector<Point>() ;
	private Vector<Point> R1505Point = new Vector<Point>() ;
	
	private HashMap<String, Vector<Point>> roomToPointMapping = new HashMap<String, Vector<Point>>() ;
	/**
     * The port that the server listens on.
     */
    private static final int PORT = 9001;
    //private static final int PORT = 8890;
    private NavigationView tagModel ;
    
    ServerSocket listener;
    
	public static int gameWindowLength = 600 ;
	public static int gameWindowWidth = 600 ;
	public static int RECTANGLE_WIDTH = 10;
	public static int RECTANGLE_HIGHT = 10;
	
	public void removeClient(EkahauClientListener pl){
		
		playerList.remove(pl);
		
	}
	public void addPlayer(EkahauClientListener player){
		
		 playerList.add(player);
	}
	
	public ServicesProvidor(NavigationView view){
		
		try {
			
			this.tagModel = view ;
			
			roomsList.add("A1501") ;
			roomsList.add("A1502") ;
			roomsList.add("A1503") ;
			roomsList.add("A1504") ;
			roomsList.add("A1505") ;
			roomsList.add("A1506") ;
			roomsList.add("A1507") ;
			roomsList.add("A1508") ;
			roomsList.add("A1509") ;
			
			R1501Point.add(new Point(484,975)) ;
			
			R1505Point.add(new Point(490,748)) ;
			
			R1506Point.add(new Point(490,650)) ;
			R1506Point.add(new Point(490,753)) ;
			R1506Point.add(new Point(490,607)) ;
			R1506Point.add(new Point(490,633)) ;
			R1506Point.add(new Point(486,435)) ;
			R1506Point.add(new Point(488,420)) ;
			R1506Point.add(new Point(489,426)) ;
			R1506Point.add(new Point(489,425)) ;
			R1506Point.add(new Point(487,458)) ;
			
			roomToPointMapping.put("A1501", R1501Point) ;
			roomToPointMapping.put("A1506", R1506Point) ;
			roomToPointMapping.put("A1505", R1505Point) ;
			
			listener = new ServerSocket(PORT);
			
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}
	
	public String getPersonLocationSource(){
		
		TagInfo tInfo = tagModel.getTagInfo("00:18:8e:20:41:60") ;
		
		Point point = tInfo.getPoint() ;
		
		//check if point is part of the already calibrated data.
		Set<String> kSet = roomToPointMapping.keySet() ;
		
		Iterator<String> kIteratgor = kSet.iterator() ;
		
		while(kIteratgor.hasNext()){
			String key = kIteratgor.next() ;
			Vector pointMap = roomToPointMapping.get(key) ;
			
			if(pointMap != null){
				Iterator<Point > roomPointMapping = pointMap.iterator() ;
				while(roomPointMapping.hasNext()){
					Point myPoint = roomPointMapping.next() ;
					if((myPoint.x == point.x || (myPoint.x - 4 <= point.x && myPoint.x + 4 >= point.x)) 
					   && (myPoint.y == point.y || (myPoint.y - 4 <= point.y && myPoint.y + 4 >= point.y))){
						
						return key ;
					}
				}
			}
		}
		
		return null ;
	}
	/**
     * The appplication main method, which just listens on a port and
     * spawns handler threads.
     */
    public static void main(String[] args) throws Exception {
        
    	System.out.println("Services server is running.");
    	ServicesProvidor servicesProvidor = new ServicesProvidor(null);
        
        try {
            while (true) {
            	
               EkahauClientListener eClient = new EkahauClientListener(servicesProvidor.listener.accept(),servicesProvidor);
               servicesProvidor.addPlayer(eClient);
               
            }
        } finally {
            servicesProvidor.listener.close();
        }
    }
    
    public void run(){
        
    	System.out.println("Services server is running.");
    	
        
        try {
            while (true) {
            	
            	Socket socket = this.listener.accept() ;
            	ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
       	    
            	Object object = input.readObject();
            	
               
	               if(object instanceof String){
	               	Bundle bundle = ActivatorPlugin.getDefault().getBundle();
	               	
	               	try {
	               		    String sourceLocation = getPersonLocationSource() ;
	               		    FileInputStream fis ;
	               		    
	               		    if(object != null)
	               		    	fis = getLocationMap( (String ) object);               		    	
	               		    else
	               		    	fis = getLocationMap(null);
	               		    
							byte[] buffer = new byte[fis.available()];
							fis.read(buffer);
							ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()) ;
							oos.writeObject(buffer);
							
							
						} catch (Exception e) {
							
							e.printStackTrace();
						}
	               }
               if (object instanceof ServicesClientRequest) {
               
	               	ServicesClientRequest pPosition = (ServicesClientRequest)object;  
	               	
	               	if(pPosition.getPreferenceType() == PREFERENCE_TYPE.ALL){
	               		
	               		ServicesClientResponse info = RestaurantsDB.getListByZOne(pPosition.getZoneType());
	               		ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream()) ;
	               				objOut.writeObject(info);
	           			objOut.flush();
	               	
	               	}else{
	               		
	               		ServicesClientResponse info = RestaurantsDB.getListType(pPosition.getPreferenceType(), pPosition.getZoneType());
	               		ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream()) ;
           				objOut.writeObject(info);
           				objOut.flush();
	               	
	               	}
               }
            }
        } catch(Exception e){
        	
        }finally {
        	
            try {
				listener.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
    }
    
    /**
     * 
     * @param loc
     * @return
     */
    FileInputStream getLocationMap(String loc){
    	
    	try {
    		
	    	if(loc != null)
			
					return new FileInputStream(ActivatorPlugin.getDefault().getBundle().getLocation().substring("reference:file:/".length()) + "icons/" +  getPersonLocationSource() + "_" + (String)loc + ".JPG" ) ;
				
			else
				
			    new FileInputStream("C:\\Documents and Settings\\ssr\\Desktop\\Ekahau_Src_\\EkahauClient\\icons\\A1500_korridoren.jpg" );
	    	
		} catch (FileNotFoundException e) {
			
			e.printStackTrace();
			
		}
		return null ;
    }
}
